package main;

import main.Link.LinkArray;
import main.Link.SQLLink;
import main.SQL.MsSQLConnect;
import main.Trees.ProjectNode;
import main.reports.XLSReportTaskSmet;
import org.jdesktop.swingx.JXTreeTable;
import org.jdesktop.swingx.decorator.ColorHighlighter;
import org.jdesktop.swingx.decorator.PatternPredicate;

import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.border.EtchedBorder;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.math.RoundingMode;
import java.sql.*;
import java.util.*;

/**
 * Created by s_shmakov on 01.04.14.
 */
public class KSForm extends JFrame {

    private JXTreeTable taskSmetLinkTree;
    private JTable taskSmetLinkTable;
    private JScrollPane jScrollPane;
    private DefaultTableModel taskSmetLinkModel;
    private JPanel panel;
    private ProjectNode curProject, myNode;
    private JButton hideWorks;
    private KSTreeModel ksTreeModel;
    public LinkArray linkArray;
    private ArrayList<Object[]> tableLink;
    private Connection connSQL;
    private HashMap<Integer, String> smrUnit = new HashMap<>();
    private HashMap<Integer, String> taskSection = new HashMap<>();
    private HashMap<Integer, String> taskSector = new HashMap<>();
    private HashMap<Integer, String> taskBlock = new HashMap<>();
    private HashMap<Integer, String> taskSubBlock = new HashMap<>();
    private GridBagConstraints c;
    private JScrollPane scrollForTable;
    private HashMap<Integer, SQLLink> sqlList;
    private HashMap<Integer, HashMap<Integer, Integer>> taskSQL;
    //region Статус-бар
    private JLabel statusText, statusTotalCount, statusSelectCount;
    private JToolBar statusBar;
    //endregion

    public KSForm(ProjectNode curProject, LinkArray linkArray) {
        this.curProject = curProject;
        this.linkArray = linkArray;
        this.tableLink = new ArrayList<>();
    }

    public void openKSForm() {

        setTitle("Отчет по привязке расценок смет к работам графика");
        panel = new JPanel();
        statusBar = new JToolBar();
        add(panel);
        int width = 1000;
        int height = 750;
        setSize(new Dimension(width, height));
        Dimension screensize = Toolkit.getDefaultToolkit().getScreenSize();
        setLocation(screensize.width / 2 - width / 2, screensize.height / 2 - height / 2);
        taskSmetLinkTable = new JTable(taskSmetLinkModel);

        scrollForTable = new JScrollPane(taskSmetLinkTable);
        scrollForTable.setVisible(false);

        this.myNode = new ProjectNode(curProject.getName(), curProject.getShortName(), curProject.getId(), false);
        this.myNode.setDbName(curProject.getDbName());
        this.myNode.setWbsId(curProject.getWbsId());

        ksTreeModel = new KSTreeModel(myNode, linkArray);
        ksTreeModel.fill();

        connSQL = MsSQLConnect.ConnectDB("Factage");
        try {
            CallableStatement stmt = connSQL.prepareCall("{call getSmrUnit()}");
            ResultSet rs = stmt.executeQuery();

            while (rs.next())
                this.smrUnit.put(rs.getInt("smr_id"), rs.getString("smrUnit"));

            Statement stat = connSQL.createStatement();
            rs = stat.executeQuery( "SELECT [task_id], [sector_code_desc], [section_code_desc], [block_code_desc], [subblock_code_descr] FROM task WHERE [proj_id] = '"+curProject.getId()+"' and [db_name] = '"+curProject.getDbName()+"'" );

            while (rs.next()) {
                this.taskSection.put(rs.getInt("task_id"), rs.getString("section_code_desc"));
                this.taskSector.put(rs.getInt("task_id"), rs.getString("sector_code_desc"));
                this.taskBlock.put(rs.getInt("task_id"), rs.getString("block_code_desc"));
                this.taskSubBlock.put(rs.getInt("task_id"), rs.getString("subblock_code_descr"));
            }

            rs.close();
            stat.close();

            connSQL.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }

        toHash(linkArray);

        taskSmetLinkTree = new JXTreeTable(ksTreeModel);
        taskSmetLinkTree.setSize(new Dimension(900, 650));
        formatTaskSmetLinkTree();
        taskSmetLinkTree.updateUI();

        KSTableModel taskSmetLinkModel = new KSTableModel(tableLink);
        taskSmetLinkTable.setModel(taskSmetLinkModel);
        taskSmetLinkTable.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent mouseEvent) {
                countCount();
            }

            @Override
            public void mouseReleased(MouseEvent mouseEvent) {
                countCount();
            }
        });
        formatTaskSmetLinkTable();
        taskSmetLinkTable.updateUI();

        jScrollPane = new JScrollPane(taskSmetLinkTree);
        jScrollPane.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, SystemColor.activeCaptionBorder));
        jScrollPane.setPreferredSize(new Dimension(900, 650));

        panel.setLayout(new GridBagLayout());

        //region hideWorks - кнопка вывода отчета в Excel
        hideWorks = new JButton("Выгрузить отчет в Excel");
        hideWorks.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                XLSReportTaskSmet xlsReport = new XLSReportTaskSmet(myNode);
                xlsReport.start();
            }
        });
        //endregion

        //region Визуальная формочка
        c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = 0;
        c.gridwidth = 1;
        c.insets = new Insets(5, 25, 5, 5);
        c.anchor = GridBagConstraints.EAST;
        panel.add(hideWorks, c);

        JLabel nothing = new JLabel(" ");
        c = new GridBagConstraints();
        c.gridx = 2;
        c.gridy = 0;
        c.gridwidth = 1;
        c.weightx = 1;
        c.fill = GridBagConstraints.HORIZONTAL;
        c.insets = new Insets(5, 5, 5, 5);
        c.anchor = GridBagConstraints.EAST;
        panel.add(nothing, c);

        jScrollPane = new JScrollPane(taskSmetLinkTree);
        jScrollPane.setPreferredSize(new Dimension(900, 650));

        c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = 2;
        c.gridwidth = 6;
        c.weightx = 1;
        c.weighty = 1;
        c.fill = GridBagConstraints.BOTH;
        c.insets = new Insets(25, 25, 5, 25);
        c.anchor = GridBagConstraints.WEST;
        panel.add(jScrollPane, c);

        c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = 3;
        c.gridwidth = 6;
        c.weightx = 1;
        c.weighty = 1;
        c.fill = GridBagConstraints.BOTH;
        c.insets = new Insets(25, 25, 5, 25);
        c.anchor = GridBagConstraints.WEST;
        panel.add(scrollForTable, c);

        statusBar.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.RAISED));
        statusText = new JLabel("Всего строк: ");
        statusTotalCount = new JLabel("0");
        statusSelectCount = new JLabel("0");
        JSeparator sep = new JSeparator(SwingConstants.VERTICAL);
        sep.setBackground(java.awt.SystemColor.control);
        sep.setForeground(java.awt.SystemColor.activeCaptionBorder);
        statusBar.add(statusText);
        statusBar.add(statusTotalCount);
        statusBar.add(sep);
        statusBar.add(statusSelectCount);

        c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = 4;
        c.gridwidth = 6;
        c.weightx = 1;
        c.fill = GridBagConstraints.HORIZONTAL;
        c.insets = new Insets(5, 0, 0, 0);
        c.anchor = GridBagConstraints.WEST;
        panel.add(statusBar, c);
        statusBar.setVisible(false);
        //endregion

        setVisible(true);
    }

    private void formatTaskSmetLinkTree() {

        try {
            Image iconTask = ImageIO.read(getClass().getResource("images/leaf.png"));
            taskSmetLinkTree.setLeafIcon(new ImageIcon(iconTask));
            Image iconWbs = ImageIO.read(getClass().getResource("images/wbs.png"));
            taskSmetLinkTree.setOpenIcon(new ImageIcon(iconWbs));
            taskSmetLinkTree.setClosedIcon(new ImageIcon(iconWbs));

        } catch (IOException e) {
            e.printStackTrace();
        }

        PatternPredicate leafPr = new PatternPredicate(".", 3);
        ColorHighlighter leafs = new ColorHighlighter(leafPr, Color.white, null, null, null);
        PatternPredicate rootPr = new PatternPredicate("ROOT", 1);
        ColorHighlighter rootHL = new ColorHighlighter(rootPr, new Color(100, 149, 237), Color.white, null, null);
        PatternPredicate wbsPr0 = new PatternPredicate("WBS0", 1);
        ColorHighlighter wbsHL0 = new ColorHighlighter(wbsPr0, new Color(122, 155, 218), Color.white, null, null);
        PatternPredicate wbsPr1 = new PatternPredicate("WBS1", 1);
        ColorHighlighter wbsHL1 = new ColorHighlighter(wbsPr1, new Color(144, 162, 200), Color.white, null, null);
        PatternPredicate wbsPr2 = new PatternPredicate("WBS2", 1);
        ColorHighlighter wbsHL2 = new ColorHighlighter(wbsPr2, new Color(167, 168, 181), Color.black, null, null);
        PatternPredicate wbsPr3 = new PatternPredicate("WBS3", 1);
        ColorHighlighter wbsHL3 = new ColorHighlighter(wbsPr3, new Color(189, 174, 163), Color.black, null, null);
        PatternPredicate wbsPr4 = new PatternPredicate("WBS4", 1);
        ColorHighlighter wbsHL4 = new ColorHighlighter(wbsPr4, new Color(211, 181, 144), Color.black, null, null);

        taskSmetLinkTree.setHighlighters(leafs, wbsHL0, wbsHL1, wbsHL2, wbsHL3, wbsHL4, rootHL);
        taskSmetLinkTree.setRowHeight(20);
        taskSmetLinkTree.setGridColor(new Color(219, 219, 219));
        taskSmetLinkTree.setShowGrid(true, true);

        if (taskSmetLinkTree.getColumnModel().getColumnCount() > 0) {
            taskSmetLinkTree.getColumnModel().getColumn(0).setMinWidth(90);
            taskSmetLinkTree.getColumnModel().getColumn(0).setPreferredWidth(150);
            taskSmetLinkTree.getColumnModel().getColumn(0).setMaxWidth(260);
            taskSmetLinkTree.getColumnModel().getColumn(2).setMinWidth(40);
            taskSmetLinkTree.getColumnModel().getColumn(2).setPreferredWidth(90);
            taskSmetLinkTree.getColumnModel().getColumn(2).setMaxWidth(120);
            taskSmetLinkTree.getColumnModel().getColumn(3).setMinWidth(40);
            taskSmetLinkTree.getColumnModel().getColumn(3).setPreferredWidth(60);
            taskSmetLinkTree.getColumnModel().getColumn(3).setMaxWidth(80);
            taskSmetLinkTree.getColumnModel().getColumn(4).setMinWidth(20);
            taskSmetLinkTree.getColumnModel().getColumn(4).setPreferredWidth(90);
            taskSmetLinkTree.getColumnModel().getColumn(4).setMaxWidth(120);
            taskSmetLinkTree.getColumnModel().getColumn(5).setMinWidth(20);
            taskSmetLinkTree.getColumnModel().getColumn(5).setPreferredWidth(90);
            taskSmetLinkTree.getColumnModel().getColumn(5).setMaxWidth(120);
            taskSmetLinkTree.getColumnModel().getColumn(6).setMinWidth(40);
            taskSmetLinkTree.getColumnModel().getColumn(6).setPreferredWidth(60);
            taskSmetLinkTree.getColumnModel().getColumn(6).setMaxWidth(80);
        }
        taskSmetLinkTree.expandAll();
    }

    private void formatTaskSmetLinkTable() {

        taskSmetLinkTable.setRowHeight(20);
        taskSmetLinkTable.setGridColor(new Color(219, 219, 219));

        if (taskSmetLinkTable.getColumnModel().getColumnCount() > 0) {
            taskSmetLinkTable.getColumnModel().getColumn(0).setMinWidth(20);
            taskSmetLinkTable.getColumnModel().getColumn(0).setPreferredWidth(40);
            taskSmetLinkTable.getColumnModel().getColumn(0).setMaxWidth(60);
            taskSmetLinkTable.getColumnModel().getColumn(1).setMinWidth(20);
            taskSmetLinkTable.getColumnModel().getColumn(1).setPreferredWidth(40);
            taskSmetLinkTable.getColumnModel().getColumn(1).setMaxWidth(60);
            taskSmetLinkTable.getColumnModel().getColumn(3).setMinWidth(40);
            taskSmetLinkTable.getColumnModel().getColumn(3).setPreferredWidth(100);
            taskSmetLinkTable.getColumnModel().getColumn(3).setMaxWidth(140);
            taskSmetLinkTable.getColumnModel().getColumn(4).setMinWidth(20);
            taskSmetLinkTable.getColumnModel().getColumn(4).setPreferredWidth(70);
            taskSmetLinkTable.getColumnModel().getColumn(4).setMaxWidth(120);
            taskSmetLinkTable.getColumnModel().getColumn(5).setMinWidth(20);
            taskSmetLinkTable.getColumnModel().getColumn(5).setPreferredWidth(100);
            taskSmetLinkTable.getColumnModel().getColumn(5).setMaxWidth(120);
            taskSmetLinkTable.getColumnModel().getColumn(6).setMinWidth(20);
            taskSmetLinkTable.getColumnModel().getColumn(6).setPreferredWidth(100);
            taskSmetLinkTable.getColumnModel().getColumn(6).setMaxWidth(120);
        }
    }

    private void countCount() {
        statusSelectCount.setText("Выбрано строк: " + taskSmetLinkTable.getSelectedRowCount());
    }

    private void toHash(LinkArray linkArray) {
        sqlList = new HashMap<>();
        taskSQL = new HashMap<>();
        HashMap<Integer, Integer> tempSet;
        for (SQLLink sql : linkArray.getLinkArray()) {
            sqlList.put(sql.getId(), sql);
            tempSet = new HashMap<>();
            if (taskSQL.get(sql.getTaskId()) != null) {
                for (Integer i : taskSQL.get(sql.getTaskId()).values()) {
                    tempSet.put(i, i);
                }
                tempSet.put(sql.getId(), sql.getId());
                taskSQL.put(sql.getTaskId(), tempSet);
            } else {
                tempSet.put(sql.getId(), sql.getId());
                taskSQL.put(sql.getTaskId(), tempSet);
            }
        }
        addSmetHash(myNode);
    }

    private void addSmetHash(ProjectNode node) {
//        System.out.println("nodeName = " + node.getName() + "| children count = " + node.getChildCount());
        for (ProjectNode work : node.getChildren()) {
            if (!work.isTask() && work.getChildren() != null) {
                addSmetHash(work);
            } else {
                work.setSection(taskSection.containsKey(work.getId()) ? taskSection.get(work.getId()) : "");
                work.setSector(taskSector.containsKey(work.getId()) ? taskSector.get(work.getId()) : "");
                work.setBlock(taskBlock.containsKey(work.getId()) ? taskBlock.get(work.getId()) : "");
                work.setSubBlock(taskSubBlock.containsKey(work.getId()) ? taskSubBlock.get(work.getId()) : "");

                if (taskSQL.get(work.getId()) != null) {
                    ArrayList<Integer> taskSQLList = new ArrayList<>(taskSQL.get(work.getId()).values());
                    Collections.sort(taskSQLList, new Comparator<Integer>() {

                        @Override
                        public int compare(Integer integer, Integer integer2) {
                            if (integer < integer2) {
                                return -1;
                            } else if (integer > integer2) {
                                return 1;
                            }
                            return 0;
                        }
                    });
                    for (Integer sql : taskSQLList) {
                        SQLLink s = sqlList.get(sql);
                        work.add(new ProjectNode(s.getSmrNum(), s.getSmrName(), s.getSmNum(), smrUnit.get(s.getSmrId()), s.getSmrVol().doubleValue(), s.getFact().divide(s.getFactFull(), 6, RoundingMode.HALF_UP).multiply(s.getSmrVol()).setScale(6, RoundingMode.HALF_UP).doubleValue(), s.getPv(), s.getPvVol().doubleValue(), s.getMrVol().doubleValue(), s.getMechVol().doubleValue(), s.getTVol().doubleValue()));
                    }
                }
            }
        }
    }
}
